package cn.ilikes.tools.hbase.jpa.query.sql.element;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.persistence.Parameter;

import cn.ilikes.tools.hbase.jpa.JPAHbasePersistenUnitEnv;
import cn.ilikes.tools.hbase.jpa.SysConfigs;
import cn.ilikes.tools.hbase.jpa.indexs.Indexer;
import cn.ilikes.tools.hbase.jpa.indexs.lucenes.LuceneQueryUtils;
import cn.ilikes.tools.hbase.jpa.metadatas.IEntityMetaData;
import cn.ilikes.tools.hbase.jpa.metadatas.IEntityMetaDataFactory;
import cn.ilikes.tools.hbase.jpa.metadatas.elements.EntityFields;
import cn.ilikes.tools.hbase.jpa.query.iquerys.IQuery;
import cn.ilikes.tools.hbase.jpa.query.iquerys.JPAHBaseQuery;
import cn.ilikes.tools.hbase.jpa.query.pasers.ParentWhereList;
import cn.ilikes.tools.hbase.jpa.query.sql.element.Properties.Between;
import cn.ilikes.tools.hbase.jpa.query.sql.element.WhereList.ListType;
import cn.ilikes.tools.untils.HBaseUtils;
import cn.ilikes.tools.untils.PropertyAccessorHelper;

public class KuTable {

	private String tableName;

	private String aliasName;

	private WhereList whereList;

	private List<GroupBy> groupBy = new ArrayList<GroupBy>();

	public KuTable() {

	}

	public List<GroupBy> getGroupBy() {
		return groupBy;
	}

	public void setGroupBy(List<GroupBy> groupBy) {
		this.groupBy = groupBy;
	}

	public String getTableName() {
		return tableName;
	}

	public String getAliasName() {
		return aliasName;
	}

	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

	public void setAliasName(String aliasName) {
		this.aliasName = aliasName;
	}

	public WhereList getWhereList() {
		return whereList;
	}

	public void setWhereList(WhereList whereList) {
		this.whereList = whereList;
	}

	@Override
	public String toString() {
		return "KuTable [tableName=" + tableName + ", aliasName=" + aliasName + ", whereList=" + toWhere() + "]";
	}

	/**
	 * 对 select s from S s where s=':s' :s赋值
	 */
	public void initVariable(Map<Parameter<?>, Object> parameters) {
		assignVariable(whereList, parameters);
	}

	public String createLunceQuery(String entityName, IEntityMetaData entityMetaData) {
		StringBuffer result = new StringBuffer();
		//result.append("->[ ");
		assignLunceVariable(entityName, whereList, entityMetaData, result);
		//result.append(" ]<-");
		return result.toString();
	}

	/**
	 * 赋值
	 * 
	 * @param element
	 * @param parameters
	 */
	private void assignLunceVariable(String entityName, Element element, IEntityMetaData entityMetaData, StringBuffer result) {
		JPAHbasePersistenUnitEnv hbasePersistenUnitEnv = entityMetaData.getJPAHbasePersistenUnitEnv();
		IEntityMetaDataFactory entityMetaDataFactory = hbasePersistenUnitEnv.getEntityMetaDataFactory();

		if (element instanceof WhereList) {
			if (element instanceof ParentWhereList) {
				result.append("( ");
			}
			WhereList whereList = (WhereList) element;
			assignLunceVariable(entityName, whereList.getLeftList(), entityMetaData, result);
			if (!whereList.getListType().equals(ListType.parent)) {
				switch (whereList.getListType()) {
				case equals: {
					result.append(":");
					break;
				}
				case like:
				case between: {
					result.append(":");
					break;
				}
				default: {
					result.append("  " + whereList.getListType().toString().toUpperCase() + " ");
				}
				}
			}
			assignLunceVariable(entityName, whereList.getRightList(), entityMetaData, result);
			if (element instanceof ParentWhereList) {
				result.append(" )");
			}
		}
		if (element instanceof Properties) {
			Properties properties = (Properties) element;
			if (properties.getType().equals(Properties.Type.value)) {
				Object value = ((Properties) element).getValue();
				if (value instanceof Between) {
					Between between = (Between) value;
					result.append("[ " + between.getStart() + " TO " + between.getEnd() + "]");

				} else {
					Object va = ((Properties) element).getValue();
					if (va.toString().toUpperCase().equals(IQuery.SQL_NULL_VALUES))
						va = Indexer.index_fields_null;
					result.append(va + " ");
				}
			} else {
				String[] tok = ((String) ((Properties) element).getValue()).split(SysConfigs.jpa_entity_table_field);
				EntityFields dntityFields = entityMetaData.getEntityFields().get(tok[1]);
				String columnName = null;
				if (dntityFields.getjPAField().isRelation()) {
					columnName = dntityFields.getjPAField().getRelation().getJoinColumnName();

				} else {
					columnName = dntityFields.getjPAField().getColumnName();
				}
				int index = columnName.indexOf(SysConfigs.hbase_column_family_qualifier);
				String family = HBaseUtils.getfamily(columnName, index);
				String qualifier = HBaseUtils.getQualifier(columnName, index);
				String luceneFieldsName = LuceneQueryUtils.createLuceneFieldsName(entityName, family, qualifier);
				//				result.append("+" + luceneFieldsName);
				result.append(" " + luceneFieldsName);
			}

		}

	}

	/**
	 * 赋值
	 * 
	 * @param element
	 * @param parameters
	 */
	private void assignVariable(Element element, Map<Parameter<?>, Object> parameters) {

		if (element instanceof WhereList) {
			if (element instanceof ParentWhereList) {
				//				result.append("(");
			}
			WhereList whereList = (WhereList) element;
			assignVariable(whereList.getLeftList(), parameters);
			if (!whereList.getListType().equals(ListType.parent))
				//				result.append(" " + whereList.getListType() + " ");
				assignVariable(whereList.getRightList(), parameters);
			if (element instanceof ParentWhereList) {
				//				result.append(")");
			}
		}
		if (element instanceof Properties) {
			//			result.append(" " + ((Properties) element).getValue() + " ");
			Properties properties = (Properties) element;
			if (properties.getType().equals(Properties.Type.value)) {
				JPAHBaseQuery.assignVariable(parameters, properties);
			} else {
				properties.setValue(properties.getVariable());
			}

		}

	}

	public String toWhere() {
		StringBuffer result = new StringBuffer();
		result.append("->[ ");
		printWhereList(whereList, result);
		result.append(" ]<-");
		return result.toString();
	}

	private void printWhereList(Element element, StringBuffer result) {

		if (element instanceof WhereList) {
			if (element instanceof ParentWhereList) {
				result.append("(");
			}
			WhereList whereList = (WhereList) element;
			printWhereList(whereList.getLeftList(), result);
			if (!whereList.getListType().equals(ListType.parent))
				result.append(" " + whereList.getListType() + " ");
			printWhereList(whereList.getRightList(), result);
			if (element instanceof ParentWhereList) {
				result.append(")");
			}
		}
		if (element instanceof Properties) {
			Object value = ((Properties) element).getValue();
			if (value instanceof Between) {
				Between element_ = (Between) value;
				result.append(" " + element_.getStart() + " to  " + element_.getEnd() + " ");
			} else {
				result.append(" " + ((Properties) element).getValue() + " ");
			}

		}
	}
}
